import { Provide, Inject, Config } from '@midwayjs/decorator';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository, Brackets } from 'typeorm';
import { User } from '../entity/user';
import { MidwayHttpError } from '@midwayjs/core';
import { CacheManager } from '@midwayjs/cache';
import { Context } from '@midwayjs/koa';
import { Article } from '../entity/article';
import { Type } from '../entity/type';

@Provide()
export class ArticleService {
  @InjectEntityModel(User)
  userModel: Repository<User>;

  @InjectEntityModel(Article)
  articleModel: Repository<Article>;

  @InjectEntityModel(Type)
  typeModel: Repository<Type>;

  @Config('jwt')
  config: any;

  @Inject()
  cacheManager: CacheManager;

  @Inject()
  ctx: Context;

  async add(data: any) {
    const {
      title,
      content,
      headPic,
      type,
      userId,
      tip,
      author,
      press,
      price,
      ISBN,
    } = data;

    const user: any = await this.userModel.findOne({
      where: { id: userId },
    });
    if (!user) {
      throw new MidwayHttpError('用户不存在!', 500);
    }

    const typeRes: any = await this.typeModel.findOne({
      where: { id: type },
    });

    const article = new Article();
    article.title = this.ctx.security.escape(title);
    article.content = content;
    article.headPic = headPic;
    article.type = typeRes;
    article.tip = tip;
    article.user = user;
    article.sees = 0;
    article.isOfficial = 1;
    article.author = author;
    article.press = press;
    article.price = price;
    article.ISBN = ISBN;

    const result = await this.articleModel.save(article);

    return {
      code: 200,
      data: result,
      message: '发表文章成功!',
    };
  }

  async delete(data: any) {
    const { id } = data;
    const result: any = await this.articleModel
      .createQueryBuilder('article')
      .softDelete()
      .where('id=:id', { id })
      .execute();

    if (!result) {
      throw new MidwayHttpError('删除失败!', 500);
    }

    return {
      code: 200,
      data: result,
      message: '删除成功!',
    };
  }

  async finds(data: any) {
    const { pageNum, pageSize, title, type } = data;
    const skip: number = (pageNum - 1) * pageSize;
    const result: any = await this.articleModel
      .createQueryBuilder('article')
      .leftJoinAndSelect('article.type', 'type')
      // .where('article.title LIKE :likeTitle', { likeTitle: `%${title}%` })
      .where(
        new Brackets(qb => {
          if (type) {
            qb.where('type.code = :type', {
              type: `${type}`,
            });
          }

          if (title) {
            qb.andWhere('article.title LIKE :likeTitle', {
              likeTitle: `%${title}%`,
            });
            // qb.where('article.content LIKE :likeTitle', {
            //   likeTitle: `%${title}%`,
            // });
          }
        })
      )
      .skip(skip)
      .take(pageSize)
      .getManyAndCount();

    if (!result) {
      throw new MidwayHttpError('没有查到文章!', 500);
    }

    return {
      code: 200,
      data: result[0],
      total: result[1],
      message: '查询文章列表成功!',
    };
  }

  async findHots(data: any) {
    let { take } = data;
    take = take || 5;
    const result: any = await this.articleModel
      .createQueryBuilder('article')
      .leftJoinAndSelect('article.type', 'type')
      .orderBy('article.sees', 'DESC')
      .take(take)
      .getManyAndCount();

    if (!result) {
      throw new MidwayHttpError('没有查到文章!', 500);
    }

    return {
      code: 200,
      data: result[0],
      total: result[1],
      message: '查询文章列表成功!',
    };
  }

  async find(data: any) {
    const { id } = data;

    const article: any = await this.articleModel.findOne({
      where: { id },
      relations: ['user', 'type'],
    });

    article.sees += 5;

    await this.articleModel.save(article);

    if (!article) {
      throw new MidwayHttpError('没有查到文章!', 500);
    }

    return {
      code: 200,
      data: article,
      message: '查询文章成功!',
    };
  }

  async update(data: any) {
    const {
      id,
      title,
      content,
      headPic,
      type,
      tip,
      author,
      press,
      price,
      ISBN,
    } = data;

    const article: any = await this.articleModel.findOne({
      where: { id },
    });

    const typeRes: any = await this.typeModel.findOne({
      where: { id: type },
    });

    article.title = this.ctx.security.escape(title);
    article.content = content;
    article.headPic = headPic;
    article.type = typeRes;
    article.tip = tip;
    article.author = author;
    article.press = press;
    article.price = price;
    article.ISBN = ISBN;

    const result = await this.articleModel.save(article);

    return {
      code: 200,
      data: result,
      message: '更新文章成功!',
    };
  }
}
